-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add bindings for AutomotiveSimulator #177
Conversation
+@EricCousineau-TRI for a more authoritative review. FYI: This is slightly related to RobotLocomotion/drake#7660. ATM I ported only the small subset of AutomotiveSimulator methods we use and the SimpleCarState class. I'm not sure it's significant enough to deserve starting an automotive pydrake module, if not, feel free to grab whatever is here when the work of binding the AutomotiveSimulator starts on the Drake side |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a little confused by this merge, as it seems to combine the unmerged #172 here.
Could you change the merge base in GitHub to be this PR, and then change it back to AUtomotiveSimulatorPort
once it has merged?
backend/CMakeLists.txt
Outdated
@@ -1,5 +1,9 @@ | |||
include (${project_cmake_dir}/Utils.cmake) | |||
include_directories(${PYTHON_INCLUDE_DIRS}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW Should this just rely solely on pybind11::module
, and not need the include_directories
?
Also, I think the Python include directories should be a transitive dependency of pybind11
- could it be removed here (if you're not using it directly)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah that's what I thought as well but noticed that it was currently not the case. If I remove this line:
In file included from /home/mikael/work/delphyne_demo/install/include/pybind11/pytypes.h:12:0,
from /home/mikael/work/delphyne_demo/install/include/pybind11/cast.h:13,
from /home/mikael/work/delphyne_demo/install/include/pybind11/attr.h:13,
from /home/mikael/work/delphyne_demo/install/include/pybind11/pybind11.h:43,
from /home/mikael/work/delphyne_demo/src/delphyne/backend/simulation_runner.cc:39:
/home/mikael/work/delphyne_demo/install/include/pybind11/detail/common.h:111:20: fatal error: Python.h: No such file or directory
I agree that this should be provided by the pybind module and I think pybind doest the right thing as I don't need this line if I use pybind built with CMake. There must be something fishy happening when building it with bazel that doesnt walk the imported target properly.
I'm in favor of leaving it for now as it allows us to move forward, I can ticket it on the Drake repo and or add a todo in this repo.
backend/simulation_runner.cc
Outdated
@@ -94,22 +96,37 @@ SimulatorRunner::SimulatorRunner( | |||
ignerr << "Error advertising service [" << kRobotRequestServiceName | |||
<< "]" << std::endl; | |||
} | |||
// Initialize the python machinery so we can invoke a python callback | |||
// function on each simulation step. | |||
Py_Initialize(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a tad confused.... Why does this need Py_Initialize
if this can be created from Python?
Is this so you can effectively call Python functions directly from C++?
Could you isolate your call sites from pure C++ to Python (which I believe would be better) and use pybind11::scoped_interpreter
? http://pybind11.readthedocs.io/en/stable/advanced/embedding.html#getting-started
If not, is there a way to check if Python has already been initialized?
Yes sorry it's uneasy to review. I tried to highlight in the PR description what commits were actually new in this PR. I'll change the base branch to facilitate review and switch it back after as you suggested. |
This is now using AutomotiveSimulatorPort_merge_master as a base |
#176 landed, switch base branch back to AutomotiveSimulatorPort |
Thanks!
My preference would be to introduce That being said, I'd hate for this to slow y'all down for short-term PRs and such. |
backend/CMakeLists.txt
Outdated
find_package(Boost COMPONENTS python REQUIRED) | ||
include_directories(${Boost_INCLUDE_DIR}) | ||
find_package(pybind11 REQUIRED) | ||
include_directories(${pybind11_INCLUDE_DIRS}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is include_directories
still needed if using pybind11::module
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right that's not needed now that we use the exported target, thanks!
backend/python_bindings_example.py
Outdated
|
||
from pydrake.common import AddResourceSearchPath | ||
|
||
from simulation_runner_py import AutomotiveSimulator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider importing multiple symbols using a single import
statement:
from simulation_runner_py import (
AutomotiveSimulator,
SimpleCarState,
SimulatorRunner,
)
backend/simulation_runner_py.cc
Outdated
// .def("GetCurrentPoses", &AutomotiveSimulator<double>::GetCurrentPoses) | ||
; | ||
// TODO(mikaelarguedas) check with @EricCousineau-TRI for moving this to pydrake | ||
py::class_<SimpleCarState<double>>(m, "SimpleCarState") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Following up from my comment on the issue thread, and since Jon requested this, I'll go ahead and submit a PR with this in it. (Feel free to fork that PR if you need more things.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, thanks!
Thanks for the comments @EricCousineau-TRI ! Yes, we will submit our changes to Drake, we just needed this code to work on other fronts, so decided to push all the bindings in this PR. As soon as we return from the holidays I will split the code and send the required PRs. |
remove unnecessary include_directories and find_package since SearchForStuff CMake refactor import multiple symbols in simgle import call
add todo for contributing some bindings upstream
1e1312f
to
06edbb0
Compare
Thank you both for the feedback! I addressed some comments and responded to other. rebased and squashed to have cleaner commit history |
AutomotiveSimulator, | ||
SimpleCarState, | ||
SimulatorRunner | ||
) | ||
|
||
|
||
def get_from_env_or_fail(var): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW Below, the stripping could be done by value.rstrip(' :')
.
backend/simulation_runner_py.cc
Outdated
return std::make_unique<SimulatorRunner>(std::move(simulator), time_step); | ||
})) | ||
.def("Start", &SimulatorRunner::Start) | ||
.def("Stop", &SimulatorRunner::Stop) | ||
.def("AddStepCallback", &SimulatorRunner::AddStepCallback); | ||
; | ||
py::class_<AutomotiveSimulator<double>, std::unique_ptr<AutomotiveSimulator<double>>>(m, "AutomotiveSimulator") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW Specifying unique_ptr
as the holder type is redundant; if you're going to always specify, I'd suggest making an extension of py::class_
to handle these things by default for you.
(At some point in the near future, I'll be introducing something like pydrake::class_
or something like that, for this and other facets.)
Thanks @EricCousineau-TRI for the review, comments adressed in 57dea01 |
Merging this. |
|
||
// Instantiate the simulator runner and pass the simulator. | ||
const double time_step = 0.001; | ||
.def(py::init([](std::unique_ptr<AutomotiveSimulator<double>> simulator, double time_step) { | ||
return std::make_unique<SimulatorRunner>(std::move(simulator), time_step); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a heads up (sorry for adding this post-merge): You should be able to use py::init<Args...>()
as a shorthand for py::init([](Args&& args...) { return make_unique<...>(...); }
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @EricCousineau-TRI , done in f3232e0
This adds the bindings required to instantiate and configure the AutomotiveSimulator from Python.
This includes the commits from #176 pending it getting merged.
In the meantime the porting is done in:
1ef6b7c
And the missing bindings are documented in bbbffe1 with the classes the need to be bind before being able to use them
fixes #165